package xdman.ui.components;

import xdman.*;
import xdman.downloaders.metadata.DashMetadata;
import xdman.downloaders.metadata.HdsMetadata;
import xdman.downloaders.metadata.HlsMetadata;
import xdman.downloaders.metadata.HttpMetadata;
import xdman.monitoring.BrowserMonitor;
import xdman.network.http.HeaderCollection;
import xdman.network.http.HttpHeader;
import xdman.ui.res.ColorResource;
import xdman.ui.res.FontResource;
import xdman.ui.res.ImageResource;
import xdman.ui.res.StringResource;
import xdman.util.FFmpegDownloader;
import xdman.util.Logger;
import xdman.util.StringUtils;
import xdman.util.XDMUtils;

import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import java.awt.*;
import java.awt.desktop.AppReopenedListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.*;

import static xdman.util.XDMUtils.getScaledInt;

public class MainWindow extends XDMFrame implements ActionListener {
    private static final long serialVersionUID = -3119522563540700138L;

    CustomButton btnTabArr[];
    CustomButton btnSort;
    CustomButton btnQueue;
    JTextField txtSearch;
    JMenuItem[] sortItems;
    String[][] sortStatusText;
    JLabel[] lblCatArr;
    SidePanel sp;
    DownloadListView lv;
    JPopupMenu popupCtx;
    JMenu startQMenu, stopQMenu, convertMenu;

    JPanel toolbar;
    UpdateNotifyPanel updateNotifyPanel;
    JLabel btnMonitoring;

    private Box rightbox; // holds tabs, menu and window control buttons

    public MainWindow() {
        setTitle(XDMApp.XDM_WINDOW_TITLE);
        setWindowSizeAndPosition();
        initWindow();
        if (Config.getInstance().isFirstRun()) {
            SettingsPage.getInstance().showPanel(this, "BTN_MONITORING");
        }
        showNotification();
        Config.getInstance().addConfigListener(new MonitoringListener() {

            @Override
            public void configChanged() {
                btnMonitoring.setIcon(
                        Config.getInstance().isBrowserMonitoringEnabled() ? ImageResource.getIcon("on.png", 85, 21)
                                : ImageResource.getIcon("off.png", 85, 21));
            }
        });
    }

//	@Override
//	protected void registerTitlePanel(JPanel panel) {
//		showTwitterIcon = true;
//		showFBIcon = true;
//		showGitHubIcon = true;
//		fbUrl = "https://www.facebook.com/XDM.subhra74/";
//		twitterUrl = "https://twitter.com/XDM_subhra74";
//		gitHubUrl = "https://github.com/subhra74/xdm";
//		super.registerTitlePanel(panel);
//	}

    private String getQueueName(String str) {
        if (str == null) {
            return "ALL";
        }
        int index = str.indexOf(":");
        if (index > 0) {
            return str.substring(index + 1);
        }
        return "ALL";
    }

    private void filterQueue(String name, Config config) {
        String qName = getQueueName(name);
        config.setQueueIdFilter(qName);
        System.out.println("filter queue name: " + qName);

        filter();
        String text = StringResource.get("LBL_ALL_QUEUE");
        if (!qName.equals("ALL")) {
            if (StringUtils.isNullOrEmptyOrBlank(qName)) {
                text = QueueManager.getInstance().getDefaultQueue().getName();
            } else {
                text = QueueManager.getInstance().getQueueById(qName).getName();
            }
        }
        btnQueue.setText(text);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        Config config = Config.getInstance();
        if (e.getSource() instanceof JComponent) {
            String name = ((JComponent) e.getSource()).getName();
            if (name == null) {
                return;
            }
            if (name.startsWith("Q_VIEW:")) {
                filterQueue(name, config);
            }
            if (name.startsWith("STOP")) {
                stopQueue(name);
            } else if (name.equals("OPT_UPDATE_FFMPEG")) {
                updateFFmpeg();
            } else if (name.startsWith("OPT_CONVERT")) {
                convert();
            } else if (name.startsWith("START")) {
                startQueue(name);
            } else if ("ADD_URL".equals(name) || "MENU_ADD_URL".equals(name)) {
                XDMApp.getInstance().addDownload(null, null);
            } else if ("ALL_DOWNLOADS".equals(name)) {
                tabClicked(e);
                config.setStateFilter(XDMConstants.ALL);
                filter();
            } else if ("ALL_UNFINISHED".equals(name)) {
                tabClicked(e);
                config.setStateFilter(XDMConstants.UNFINISHED);
                filter();
            } else if ("ALL_FINISHED".equals(name)) {
                tabClicked(e);
                config.setStateFilter(XDMConstants.FINISHED);
                filter();
            } else if ("PAUSE".equals(name) || "MENU_PAUSE".equals(name)) {
                pauseDownloads();
            } else if ("CTX_COPY_URL".equals(name)) {
                String[] ids = lv.getSelectedIds();
                if (ids.length > 0) {
                    String id = ids[0];
                    XDMUtils.copyURL(XDMApp.getInstance().getURL(id));
                }
            } else if ("LBL_SHOW_PROGRESS".equals(name)) {
                String[] ids = lv.getSelectedIds();
                if (ids.length > 0) {
                    String id = ids[0];
                    XDMApp.getInstance().showPrgWnd(id);
                }
            } else if ("MENU_RESTART".equals(name)) {
                String[] ids = lv.getSelectedIds();
                for (String id : ids) {
                    XDMApp.getInstance().restartDownload(id);
                }
            } else if ("RESUME".equals(name) || "MENU_RESUME".equals(name)) {
                String[] ids = lv.getSelectedIds();
                for (String id : ids) {
                    XDMApp.getInstance().resumeDownload(id, true);
                }
            } else if ("CTX_OPEN_FILE".equals(name)) {
                openFile();
            } else if ("CTX_OPEN_FOLDER".equals(name)) {
                String[] ids = lv.getSelectedIds();
                if (ids.length > 0) {
                    String id = ids[0];
                    openFolder(id);
                }
            } else if ("MENU_EXIT".equals(name)) {
                XDMApp.getInstance().exit();
            } else if ("0".equals(name)) {
                config.setSortField(0);
                filter();
            } else if ("1".equals(name)) {
                config.setSortField(1);
                filter();
            } else if ("2".equals(name)) {
                config.setSortField(2);
                filter();
            } else if ("3".equals(name)) {
                config.setSortField(3);
                filter();
            } else if ("4".equals(name)) {
                config.setSortAsc(true);
                filter();
            } else if ("5".equals(name)) {
                config.setSortAsc(false);
                filter();
            } else if ("BTN_SEARCH".equals(name)) {
                config.setSearchText(txtSearch.getText());
                filter();
            } else if ("CAT_DOCUMENTS".equals(name)) {
                config.setCategoryFilter(XDMConstants.DOCUMENTS);
                updateSidePanel((JLabel) e.getSource());
            } else if ("CAT_COMPRESSED".equals(name)) {
                config.setCategoryFilter(XDMConstants.COMPRESSED);
                updateSidePanel((JLabel) e.getSource());
            } else if ("CAT_MUSIC".equals(name)) {
                config.setCategoryFilter(XDMConstants.MUSIC);
                updateSidePanel((JLabel) e.getSource());
            } else if ("CAT_PROGRAMS".equals(name)) {
                config.setCategoryFilter(XDMConstants.PROGRAMS);
                updateSidePanel((JLabel) e.getSource());
            } else if ("CAT_VIDEOS".equals(name)) {
                config.setCategoryFilter(XDMConstants.VIDEO);
                updateSidePanel((JLabel) e.getSource());
            } else if ("CAT_ALL".equals(name)) {
                config.setCategoryFilter(XDMConstants.ALL);
                updateSidePanel((JLabel) e.getSource());
            } else if ("MENU_CLIP_ADD".equals(name)) {
                int ret = MessageBox.show(this, "sample title",
                        "sample textdgdfgdfgdfghdfh gfhsdgh gfgfh dfgdfqwewrqwerwerqwerqwerwerwqerqwerqwerqwerwerwegfterj jgh ker gwekl hwgklerhg ek hrkjlwhlk kj hgeklgh jkle herklj gheklwerjgh sample textdgdfgdfgdfghdfh gfhsdgh gfgfh dfgdfqwewrqwerwerqwerqwerwerwqerqwerqwerqwerwerwegfterj jgh ker gwekl hwgklerhg ek hrkjlwhlk kj hgeklgh jkle herklj gheklwerjgh",
                        MessageBox.OK_OPTION, MessageBox.OK);
                System.out.println("After: " + ret);
                // new DownloadCompleteWnd().setVisible(true);
            } else if ("MENU_OPTIONS".equals(name) || "OPTIONS".equals(name)) {
                SettingsPage.getInstance().showPanel(this, "PG_SETTINGS");
            } else if ("MENU_REFRESH_LINK".equals(name)) {
                openRefreshPage();
            } else if ("MENU_PROPERTIES".equals(name)) {
                showProperties();
            } else if ("MENU_BROWSER_INT".equals(name)) {
                SettingsPage.getInstance().showPanel(this, "BTN_MONITORING");
            } else if ("MENU_SPEED_LIMITER".equals(name)) {
                int ret = SpeedLimiter.getSpeedLimit();
                if (ret >= 0) {
                    Config.getInstance().setSpeedLimit(ret);
                }
            } else if ("DESC_Q_TITLE".equals(name)) {
                SettingsPage.getInstance().showPanel(this, "Q_MAN");
            } else if ("MENU_MEDIA_CONVERTER".equals(name)) {
                convert();
            } else if ("MENU_DELETE_DWN".equals(name) || "DELETE".equals(name)) {
                if (MessageBox.show(this, StringResource.get("DEL_TITLE"), StringResource.get("DEL_SEL_TEXT"),
                        MessageBox.YES_NO_OPTION, MessageBox.YES,
                        StringResource.get("LBL_DELETE_FILE")) == MessageBox.YES) {
                    String[] ids = lv.getSelectedIds();
                    ArrayList<String> idList = new ArrayList<>();
                    Collections.addAll(idList, ids);
                    XDMApp.getInstance().deleteDownloads(idList, MessageBox.isChecked());
                }
            } else if ("MENU_DELETE_COMPLETED".equals(name)) {
                if (MessageBox.show(this, StringResource.get("DEL_TITLE"), StringResource.get("DEL_FINISHED_TEXT"),
                        MessageBox.YES_NO_OPTION, MessageBox.YES) == MessageBox.YES) {
                    XDMApp.getInstance().deleteCompleted();
                }
            } else if ("MENU_ABOUT".equals(name)) {
                AboutPage aboutPage = new AboutPage(this);
                aboutPage.showPanel();
            } else if ("CTX_SAVE_AS".equals(name)) {
                String[] ids = lv.getSelectedIds();
                if (ids.length > 0) {
                    String id = ids[0];
                    changeFile(id);
                }
            } else if ("MENU_VIDEO_DWN".equals(name)) {
                showVideoDwnDlg();
            } else if ("MENU_IMPORT".equals(name)) {
                JFileChooser jfc = new JFileChooser();
                if (jfc.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
                    File file = jfc.getSelectedFile();
                    XDMApp.getInstance().loadDownloadList(file);
                }
            } else if ("MENU_EXPORT".equals(name)) {
                JFileChooser jfc = new JFileChooser();
                if (jfc.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) {
                    File file = jfc.getSelectedFile();
                    XDMApp.getInstance().saveDownloadList(file);
                }
            } else if ("MENU_CONTENTS".equals(name)) {
                XDMUtils.browseURL(XDMApp.APP_WIKI_URL);
            } else if ("MENU_HOME_PAGE".equals(name)) {
                XDMUtils.browseURL(XDMApp.APP_HOME_URL);
            } else if ("MENU_UPDATE".equals(name)) {
                XDMUtils.browseURL(XDMApp.APP_UPDATE_CHK_URL + XDMApp.APP_VERSION);
            } else if ("MENU_LANG".equals(name)) {
                showLanguageDlg();
            } else if ("MENU_BATCH_DOWNLOAD".equals(name)) {
                showBatchPatternDialog();
            } else if ("MENU_CLIP_ADD_MENU".equals(name)) {
                showBatchDialog();
            } else if ("DWN_PREVIEW".equals(name)) {
                String[] ids = lv.getSelectedIds();
                if (ids == null || ids.length < 1) {
                    return;
                }
                DownloadEntry ent = XDMApp.getInstance().getEntry(ids[0]);
                if (ent == null)
                    return;
                if (ent.getState() != XDMConstants.FINISHED) {
                    XDMApp.getInstance().openPreview(ent.getId());
                }
            } else if ("LBL_OPTIMIZE_NETWORK".equals(name)) {
                optimizeRWin();
            } else if ("LBL_TRANSLATE".equals(name)) {
                openTranslationPage();
            } else if ("LBL_SUPPORT_PAGE".equals(name)) {
                openSupportPage();
            } else if ("LBL_REPORT_PROBLEM".equals(name)) {
                openBugReportPage();
            }
        }
    }

    private void updateSidePanel(JLabel lbl) {
        for (JLabel jLabel : lblCatArr) {
            if (lbl == jLabel) {
                jLabel.setBackground(ColorResource.getActiveTabColor());
                jLabel.setOpaque(true);
            } else {
                jLabel.setOpaque(false);
            }
        }
        lv.refresh();
        sp.repaint();
    }

    private void filter() {
        lv.refresh();
        updateSortMenu();
        btnSort.setText(sortStatusText[Config.getInstance().getSortField()][Config.getInstance().getSortAsc() ? 1 : 0]);
    }

    private JPanel createToolbar() {
        JPanel p = new JPanel(new BorderLayout());
        Box toolBox = Box.createHorizontalBox();
        toolBox.add(Box.createRigidArea(new Dimension(scale(20), scale(60))));
        toolBox.setBackground(ColorResource.getTitleColor());
        toolBox.setOpaque(true);

        JButton btn1 = createToolButton("ADD_URL", "tool_add.png");
        btn1.setToolTipText(StringResource.get("MENU_ADD_URL"));
        toolBox.add(btn1);

        toolBox.add(Box.createRigidArea(new Dimension(scale(10), scale(10))));

        JButton btn2 = createToolButton("DELETE", "tool_del.png");
        btn2.setToolTipText(StringResource.get("MENU_DELETE_DWN"));
        toolBox.add(btn2);

        toolBox.add(Box.createRigidArea(new Dimension(scale(10), scale(10))));

        JButton btn3 = createToolButton("PAUSE", "tool_pause.png");
        btn3.setToolTipText(StringResource.get("MENU_PAUSE"));
        toolBox.add(btn3);

        toolBox.add(Box.createRigidArea(new Dimension(scale(10), scale(10))));

        JButton btn4 = createToolButton("RESUME", "tool_resume.png");
        btn4.setToolTipText(StringResource.get("MENU_RESUME"));
        toolBox.add(btn4);

        toolBox.add(Box.createRigidArea(new Dimension(scale(10), scale(10))));

        JButton btn5 = createToolButton("OPTIONS", "tool_settings.png");
        btn5.setToolTipText(StringResource.get("TITLE_SETTINGS"));
        toolBox.add(btn5);

        toolBox.add(Box.createRigidArea(new Dimension(scale(10), scale(10))));

        JButton btn6 = createToolButton("MENU_VIDEO_DWN", "tool_video.png");
        btn6.setToolTipText(StringResource.get("MENU_VIDEO_DWN"));
        toolBox.add(btn6);

        toolBox.add(Box.createRigidArea(new Dimension(scale(10), scale(10))));

        JButton btn7 = createToolButton("MENU_MEDIA_CONVERTER", "tool_convert.png");
        btn7.setToolTipText(StringResource.get("MENU_MEDIA_CONVERTER"));
        toolBox.add(btn7);
        toolBox.add(Box.createHorizontalGlue());

        btnMonitoring = new JLabel(ImageResource.getIcon("on.png", 85, 21));
        // btnMonitoring.setForeground(Color.WHITE);
        btnMonitoring.setIconTextGap(scale(15));
        btnMonitoring.putClientProperty("xdmbutton.norollover", "true");
        // btnMonitoring.setBackground(ColorResource.getTitleColor());
        btnMonitoring.setName("BROWSER_MONITORING");
        btnMonitoring.setText(StringResource.get("BROWSER_MONITORING"));
        btnMonitoring.setHorizontalTextPosition(JButton.LEADING);
        btnMonitoring.setFont(FontResource.getBigFont());

        btnMonitoring
                .setIcon(Config.getInstance().isBrowserMonitoringEnabled() ? ImageResource.getIcon("on.png", 85, 21)
                        : ImageResource.getIcon("off.png", 85, 21));

        btnMonitoring.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseReleased(MouseEvent e) {
                toggleMonitoring((JLabel) e.getSource());
            }
        });
        toolBox.add(btnMonitoring);
        toolBox.add(Box.createRigidArea(new Dimension(scale(25), scale(10))));
        p.add(toolBox);
        return p;
    }

    private JButton createToolButton(String name, String icon) {
        CustomButton btn = new CustomButton(ImageResource.getIcon(icon, 32, 32));
        btn.setPressedBackground(ColorResource.getDarkPressedColor());
        btn.setRolloverBackground(Color.DARK_GRAY);
        btn.setBorderPainted(false);
        btn.addActionListener(this);
        btn.setName(name);
        btn.setBackground(ColorResource.getTitleColor());
        btn.setMargin(new Insets(0, 0, 0, 0));
        return btn;
    }

    private SidePanel createSidePanel() {
        sp = new SidePanel();
        sp.setLayout(null);
        sp.setPreferredSize(new Dimension(scale(80), scale(250)));

        lblCatArr = new JLabel[6];

        lblCatArr[0] = createCategoryLabel("CAT_ALL");
        lblCatArr[1] = createCategoryLabel("CAT_DOCUMENTS");
        lblCatArr[2] = createCategoryLabel("CAT_COMPRESSED");
        lblCatArr[3] = createCategoryLabel("CAT_MUSIC");
        lblCatArr[4] = createCategoryLabel("CAT_VIDEOS");
        lblCatArr[5] = createCategoryLabel("CAT_PROGRAMS");

        lblCatArr[0].setBackground(ColorResource.getActiveTabColor());
        lblCatArr[0].setOpaque(true);

        for (int i = 0; i < 6; i++) {
            lblCatArr[i].setBounds(0, scale(20 + (i * 35)), scale(149), scale(27));
            final int c = i;
            lblCatArr[i].addMouseListener(new MouseAdapter() {
                public void mouseReleased(MouseEvent e) {
                    actionPerformed(new ActionEvent(lblCatArr[c], 0, ""));
                }
            });
            sp.add(lblCatArr[i]);
        }
        return sp;
    }

    private void toggleMonitoring(JLabel btn) {
        Config.getInstance().enableMonitoring(!Config.getInstance().isBrowserMonitoringEnabled());
        btn.setIcon(Config.getInstance().isBrowserMonitoringEnabled() ? ImageResource.getIcon("on.png", 85, 21)
                : ImageResource.getIcon("off.png", 85, 21));
        BrowserMonitor.getInstance().updateSettingsAndStatus();
    }

    private void createMainMenu() {
        JMenuBar bar = new JMenuBar();
        bar.setBorderPainted(false);
        bar.setForeground(ColorResource.getWhite());
        bar.setMaximumSize(new Dimension(bar.getMaximumSize().width, XDMUtils.getScaledInt(30)));
        bar.setBackground(ColorResource.getTitleColor());

        JMenu file = createMenu(StringResource.get("MENU_FILE"));

        addMenuItem("MENU_ADD_URL", file);
        addMenuItem("MENU_VIDEO_DWN", file);
        addMenuItem("MENU_CLIP_ADD_MENU", file);
        addMenuItem("MENU_BATCH_DOWNLOAD", file);
        addMenuItem("MENU_DELETE_DWN", file);
        addMenuItem("MENU_DELETE_COMPLETED", file);
        addMenuItem("MENU_EXPORT", file);
        addMenuItem("MENU_IMPORT", file);
        addMenuItem("MENU_EXIT", file);

        JMenu dwn = createMenu(StringResource.get("MENU_DOWNLOAD"));

        addMenuItem("MENU_PAUSE", dwn);
        addMenuItem("MENU_RESUME", dwn);
        addMenuItem("MENU_RESTART", dwn);
        addMenuItem("DESC_Q_TITLE", dwn);

        PopupMenuListener popupListener = new PopupMenuListener() {

            @Override
            public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
                loadQueueMenu(startQMenu);
                loadQueueMenu(stopQMenu);
            }

            @Override
            public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
            }

            @Override
            public void popupMenuCanceled(PopupMenuEvent e) {
            }
        };

        startQMenu = addSubMenu("MENU_START_Q", dwn, popupListener);
        stopQMenu = addSubMenu("MENU_STOP_Q", dwn, popupListener);

        JMenu tools = createMenu(StringResource.get("MENU_TOOLS"));

        addMenuItem("MENU_OPTIONS", tools);
        addMenuItem("MENU_REFRESH_LINK", tools);
        addMenuItem("MENU_PROPERTIES", tools);
        // addMenuItem("MENU_FORCE_ASSEMBLE", tools);
        addMenuItem("MENU_SPEED_LIMITER", tools);
        addMenuItem("MENU_LANG", tools);
        addMenuItem("MENU_MEDIA_CONVERTER", tools);
        addMenuItem("LBL_OPTIMIZE_NETWORK", tools);
        addMenuItem("MENU_BROWSER_INT", tools);

        JMenu help = createMenu(StringResource.get("MENU_HELP"));
        addMenuItem("MENU_CONTENTS", help);
        addMenuItem("MENU_HOME_PAGE", help);
        addMenuItem("LBL_SUPPORT_PAGE", help);
        addMenuItem("LBL_REPORT_PROBLEM", help);
        addMenuItem("LBL_TRANSLATE", help);
        addMenuItem("MENU_UPDATE", help);
        // addMenuItem("OPT_UPDATE_FFMPEG", help);
        addMenuItem("MENU_ABOUT", help);

        bar.add(file);
        bar.add(dwn);
        bar.add(tools);
        bar.add(help);

        // bar.setAlignmentX(Box.RIGHT_ALIGNMENT);
        // bar.setAlignmentY(Box.TOP_ALIGNMENT);

//		Box vbox1=Box.createVerticalBox();
//		vbox1.setPreferredSize(new Dimension(300, 30));
//		vbox1.setOpaque(true);
//		vbox1.setBackground(Color.RED);
//		vbox1.setMinimumSize(new Dimension(300, 30));
//		vbox1.add(bar);
//		vbox1.add(Box.createVerticalGlue());

//		JPanel panel = new JPanel(new BorderLayout());
//		Box hb1 = Box.createHorizontalBox();
//		hb1.add(Box.createHorizontalGlue());
//		hb1.add(bar);
//		hb1.add(Box.createHorizontalStrut(getScaledInt(30)));
//		panel.add(hb1, BorderLayout.NORTH);

//
//		Box menuBox = Box.createHorizontalBox();
//		menuBox.setOpaque(true);
//		menuBox.setBackground(Color.RED);
//		bar.setBackground(Color.RED);
//		//menuBox.add(Box.createHorizontalGlue());
//		menuBox.add(bar);
//		//menuBox.add(Box.createHorizontalStrut(getScaledInt(30)));
//		getTitlePanel().add(panel);

        Box menuBox = Box.createHorizontalBox();
        menuBox.setBorder(new EmptyBorder(0, 0, getScaledInt(20), 0));
        menuBox.add(Box.createHorizontalGlue());
        menuBox.add(bar);
        menuBox.add(Box.createHorizontalStrut(getScaledInt(30)));
        menuBox.add(super.createWindowButtons());
        menuBox.setAlignmentX(Box.RIGHT_ALIGNMENT);
        this.rightbox.add(menuBox);
    }

    private JMenu createMenu(String title) {
        JMenu menu = new JMenu(title);
        // menu.setForeground(ColorResource.getDeepFontColor());
        menu.setFont(FontResource.getBoldFont());
        menu.setBorderPainted(false);
        menu.setBorder(new EmptyBorder(getScaledInt(5), getScaledInt(5), getScaledInt(5), getScaledInt(5)));
        return menu;
    }

    private void addMenuItem(String id, JComponent menu) {
        JMenuItem mitem = new JMenuItem(StringResource.get(id));
        // mitem.setForeground(ColorResource.getLightFontColor());
        mitem.setName(id);
        mitem.setFont(FontResource.getNormalFont());
        mitem.addActionListener(this);
        menu.add(mitem);
    }

    private JMenu addSubMenu(String id, JMenu parentMenu, PopupMenuListener popupListener) {
        JMenu menu = new JMenu(StringResource.get(id));
        menu.setName(id);
        menu.setFont(FontResource.getNormalFont());
        // menu.setForeground(ColorResource.getLightFontColor());
        menu.addActionListener(this);
        // menu.setBackground(ColorResource.getDarkerBgColor());
        menu.setBorderPainted(false);
        menu.getPopupMenu().addPopupMenuListener(popupListener);
        parentMenu.add(menu);
        return menu;
    }

    private JLabel createCategoryLabel(String name) {
        JLabel lblCat = new JLabel(StringResource.get(name));
        lblCat.setName(name);
        lblCat.setFont(FontResource.getBigFont());
        lblCat.setForeground(Color.BLACK);
        lblCat.setBorder(new EmptyBorder(getScaledInt(5), getScaledInt(20), getScaledInt(5), getScaledInt(5)));
        return lblCat;
    }

    private CustomButton createDropdownBtn(String textKey) {
        CustomButton btn = new CustomButton(StringResource.get(textKey));
        btn.setBackground(ColorResource.getActiveTabColor());
        btn.setBorderPainted(false);
        btn.setFocusPainted(false);
        btn.setContentAreaFilled(false);
        btn.setIcon(ImageResource.getIcon("down.png", 10, 10));
        btn.setVerticalTextPosition(SwingConstants.CENTER);
        btn.setHorizontalTextPosition(SwingConstants.LEFT);
        btn.setFont(FontResource.getNormalFont());
        return btn;
    }

    private Component createSearchPane() {
        btnSort = createDropdownBtn("SORT_DATE_DESC");

        // btnSort = new CustomButton(StringResource.get("SORT_DATE_DESC"));
        // btnSort.setBackground(ColorResource.getActiveTabColor());
        // btnSort.setBorderPainted(false);
        // btnSort.setFocusPainted(false);
        // btnSort.setContentAreaFilled(false);
        // btnSort.setFont(FontResource.getNormalFont());

        btnQueue = createDropdownBtn("LBL_ALL_QUEUE");

        txtSearch = new JTextField();
        txtSearch.setBackground(Color.WHITE);
        txtSearch.setForeground(Color.BLACK);
        txtSearch.setBorder(null);
        txtSearch.setName("BTN_SEARCH");
        txtSearch.addActionListener(this);

        final CustomButton btnSearch = new CustomButton();
        btnSearch.setName("BTN_SEARCH");
        btnSearch.setRolloverBackground(Color.WHITE);
        btnSearch.setPressedBackground(Color.WHITE);
        btnSearch.addActionListener(this);
        btnSearch.setPreferredSize(new Dimension(XDMUtils.getScaledInt(20), XDMUtils.getScaledInt(20)));
        btnSearch.setBackground(Color.WHITE);
        btnSearch.setIcon(ImageResource.getIcon("search.png", 18, 18));
        btnSearch.setBorderPainted(false);
        btnSearch.setFocusPainted(false);

        txtSearch.addActionListener(this);

        Box b = Box.createHorizontalBox();
        b.setOpaque(true);
        b.setBackground(Color.WHITE);
        b.setPreferredSize(new Dimension(scale(130), scale(20)));
        b.setMaximumSize(new Dimension(scale(130), scale(20)));
        txtSearch.setPreferredSize(new Dimension(scale(70), scale(20)));
        txtSearch.setMaximumSize(new Dimension(txtSearch.getMaximumSize().width, scale(20)));
        b.add(txtSearch);
        b.add(btnSearch);
        b.setBorder(new LineBorder(Color.LIGHT_GRAY, 1));

        Box bp = Box.createHorizontalBox();
        bp.setOpaque(false);
        bp.setBorder(new EmptyBorder(scale(3), scale(3), scale(3), scale(10)));
        bp.add(Box.createHorizontalStrut(10));
        bp.add(btnQueue);
        bp.add(Box.createHorizontalGlue());
        bp.add(btnSort);
        bp.add(Box.createHorizontalStrut(10));
        bp.add(b);
        bp.add(Box.createHorizontalStrut(10));

        sortItems = new JMenuItem[6];

        sortItems[0] = new JMenuItem(StringResource.get("SORT_DATE"));
        sortItems[0].setName("0");
        sortItems[1] = new JMenuItem(StringResource.get("SORT_SIZE"));
        sortItems[1].setName("1");
        sortItems[2] = new JMenuItem(StringResource.get("SORT_NAME"));
        sortItems[2].setName("2");
        sortItems[3] = new JMenuItem(StringResource.get("SORT_TYPE"));
        sortItems[3].setName("3");

        sortItems[4] = new JMenuItem(StringResource.get("SORT_ASC"));
        sortItems[4].setName("4");
        sortItems[5] = new JMenuItem(StringResource.get("SORT_DESC"));
        sortItems[5].setName("5");

        final JPopupMenu popSort = new JPopupMenu();
        for (int i = 0; i < sortItems.length; i++) {
            popSort.add(sortItems[i]);
            if (i > 3) {
                sortItems[i].putClientProperty("bgColor", ColorResource.getDarkBgColor());
            }
            sortItems[i].addActionListener(this);
        }

        updateSortMenu();

        popSort.setInvoker(btnSort);

        btnSort.addActionListener(e -> popSort.show(btnSort, 0, btnSort.getHeight()));

        btnQueue.addActionListener(e -> prepeareQueuePopupButton());

        return bp;
    }

    private void prepeareQueuePopupButton() {
        final JPopupMenu popQ = new JPopupMenu();
        ArrayList<DownloadQueue> qlist = QueueManager.getInstance().getQueueList();

        JMenuItem[] qItems = new JMenuItem[qlist.size() + 1];
        qItems[0] = new JMenuItem(StringResource.get("LBL_ALL_QUEUE"));
        qItems[0].setName("Q_VIEW:ALL");
        popQ.add(qItems[0]);
        qItems[0].addActionListener(this);
        int index = -1;
        for (int i = 0; i < qlist.size(); i++) {
            String qId = qlist.get(i).getQueueId();
            DownloadQueue q = qlist.get(i);

            qItems[i + 1] = new JMenuItem(q.getName() + (q.isRunning() ? "*" : ""));
            qItems[i + 1].setName("Q_VIEW:" + qId);
            qItems[i + 1].addActionListener(this);
            popQ.add(qItems[i + 1]);
            String selectedQ = Config.getInstance().getQueueIdFilter();
            if (index == -1) {
                if (selectedQ != null && selectedQ.equals(qId)) {
                    index = i + 1;
                }
            }
        }

        if (index == -1) {
            index = 0;
        }

        qItems[index].setFont(FontResource.getBoldFont());
        qItems[index].setForeground(ColorResource.getLightFontColor());

        popQ.setInvoker(btnQueue);
        popQ.show(btnQueue, 0, btnQueue.getHeight());
    }

    private void updateSortMenu() {
        for (int i = 0; i < sortItems.length; i++) {
            if (i <= 3) {
                if (i == Config.getInstance().getSortField()) {
                    sortItems[i].setFont(FontResource.getBoldFont());
                    sortItems[i].setForeground(ColorResource.getLightFontColor());// (FontResource.getBoldFont());
                } else {
                    sortItems[i].setFont(FontResource.getNormalFont());
                    sortItems[i].setForeground(ColorResource.getDeepFontColor());
                }
            }
        }

        sortItems[4]
                .setFont(Config.getInstance().getSortAsc() ? FontResource.getBoldFont() : FontResource.getNormalFont());
        sortItems[4].setForeground(Config.getInstance().getSortAsc() ? ColorResource.getLightFontColor()
                : ColorResource.getDeepFontColor());
        sortItems[5].setFont(
                (!Config.getInstance().getSortAsc()) ? FontResource.getBoldFont() : FontResource.getNormalFont());
        sortItems[5].setForeground((!Config.getInstance().getSortAsc()) ? ColorResource.getLightFontColor()
                : ColorResource.getDeepFontColor());

    }

    private void createTabs() {
        CustomButton btnAllTab = new CustomButton(StringResource.get("ALL_DOWNLOADS")),
                btnIncompleteTab = new CustomButton(StringResource.get("ALL_UNFINISHED")),
                btnCompletedTab = new CustomButton(StringResource.get("ALL_FINISHED"));

        btnTabArr = new CustomButton[3];
        btnTabArr[0] = btnAllTab;
        btnTabArr[0].setName("ALL_DOWNLOADS");
        btnTabArr[1] = btnIncompleteTab;
        btnTabArr[1].setName("ALL_UNFINISHED");
        btnTabArr[2] = btnCompletedTab;
        btnTabArr[2].setName("ALL_FINISHED");

        for (int i = 0; i < 3; i++) {
            btnTabArr[i].setFont(FontResource.getBigBoldFont());
            btnTabArr[i].setBorderPainted(false);
            btnTabArr[i].setFocusPainted(false);
            btnTabArr[i].addActionListener(this);
        }

        btnAllTab.setBackground(ColorResource.getActiveTabColor());
        btnAllTab.setForeground(ColorResource.getDarkBgColor());

        btnIncompleteTab.setBackground(ColorResource.getTitleColor());
        btnIncompleteTab.setForeground(ColorResource.getDeepFontColor());

        btnCompletedTab.setBackground(ColorResource.getTitleColor());
        btnCompletedTab.setForeground(ColorResource.getDeepFontColor());

        JPanel p = new JPanel(new GridLayout(1, 3, scale(5), 0));
        p.setBorder(null);
        p.setOpaque(false);
        Dimension d = new Dimension(scale(380), scale(30));
        p.setPreferredSize(d);
        p.setMaximumSize(d);
        p.setMinimumSize(d);
        p.setBackground(Color.WHITE);
        p.add(btnAllTab);
        p.add(btnIncompleteTab);
        p.add(btnCompletedTab);

        p.setAlignmentX(Box.RIGHT_ALIGNMENT);

        this.rightbox.add(p);

        // pp.add(p, BorderLayout.EAST);

        // getTitlePanel().add(pp, BorderLayout.SOUTH);
    }

    private void tabClicked(ActionEvent e) {
        for (int i = 0; i < 3; i++) {
            if (btnTabArr[i] == e.getSource()) {
                btnTabArr[i].setBackground(ColorResource.getActiveTabColor());
                btnTabArr[i].setForeground(ColorResource.getDarkBgColor());
            } else {
                btnTabArr[i].setBackground(ColorResource.getTitleColor());
                btnTabArr[i].setForeground(ColorResource.getDeepFontColor());
            }
        }
    }

    private void initWindow() {
        setIconImage(ImageResource.getImage("icon.png"));
        /* Set Dock icon in macOS */
        try {
            Taskbar.getTaskbar().setIconImage(ImageResource.getImage("icon.png"));
        } catch (final UnsupportedOperationException | SecurityException e) {
            System.out.println("Error setting Dock icon");
        }
        /* Re-open XDM from dock on macOS */
        if (XDMUtils.detectOS() == XDMUtils.MAC) {
            Desktop.getDesktop().addAppEventListener((AppReopenedListener) e -> XDMApp.getInstance().showMainWindow());
        }

        showTwitterIcon = true;
        showFBIcon = true;
        showGitHubIcon = true;
        fbUrl = XDMApp.APP_FACEBOOK_URL;
        twitterUrl = XDMApp.APP_TWITTER_URL;
        gitHubUrl = XDMApp.APP_HOME_URL;

        JLabel lblTitle = new JLabel(XDMApp.XDM_WINDOW_TITLE);
        lblTitle.setBorder(new EmptyBorder(scale(20), scale(20), scale(20), 0));
        lblTitle.setFont(FontResource.getBiggestFont());
        lblTitle.setForeground(ColorResource.getWhite());
        getTitlePanel().add(lblTitle);
        this.rightbox = Box.createVerticalBox();

        createMainMenu();
        rightbox.add(Box.createVerticalGlue());
        createTabs();
        getTitlePanel().add(rightbox, BorderLayout.EAST);

        BarPanel bp = new BarPanel();
        bp.setLayout(new BorderLayout());
        bp.add(Box.createRigidArea(new Dimension(0, scale(30))));
        bp.add(createSearchPane(), BorderLayout.EAST);

        JPanel panCenter = new JPanel(new BorderLayout());
        panCenter.setBackground(Color.WHITE);
        panCenter.add(bp, BorderLayout.NORTH);

        JPanel pClient = new JPanel(new BorderLayout());
        pClient.add(panCenter);
        pClient.add(createSidePanel(), BorderLayout.WEST);

        toolbar = createToolbar();
        pClient.add(toolbar, BorderLayout.SOUTH);

        add(pClient);

        sortStatusText = new String[4][2];

        sortStatusText[0][0] = StringResource.get("SORT_DATE_DESC");
        sortStatusText[0][1] = StringResource.get("SORT_DATE_ASC");

        sortStatusText[1][0] = StringResource.get("SORT_SIZE_DESC");
        sortStatusText[1][1] = StringResource.get("SORT_SIZE_ASC");

        sortStatusText[2][0] = StringResource.get("SORT_NAME_DESC");
        sortStatusText[2][1] = StringResource.get("SORT_NAME_ASC");

        sortStatusText[3][0] = StringResource.get("SORT_TYPE_DESC");
        sortStatusText[3][1] = StringResource.get("SORT_TYPE_ASC");
        // test ui

        // setMenuActionListener(this);

        lv = new DownloadListView(panCenter);
        filter();

        createPopupMenu();

        ToolTipManager.sharedInstance().setInitialDelay(500);
    }

    private void setWindowSizeAndPosition() {
        if (Config.getInstance().getWidth() < 0 || Config.getInstance().getHeight() < 0)
            setSize(scale(800), scale(600));
        if (Config.getInstance().getX() < 0 || Config.getInstance().getY() < 0)
            setLocationRelativeTo(null);
    }

    private void stopQueue(String name) {
        String queueId = "";
        String[] arr = name.split(":");
        if (arr.length > 1) {
            queueId = arr[1].trim();
        }
        DownloadQueue q = XDMApp.getInstance().getQueueById(queueId);
        if (q != null) {
            q.stop();
        }
    }

    private void startQueue(String name) {
        String queueId = "";
        String[] arr = name.split(":");
        if (arr.length > 1) {
            queueId = arr[1].trim();
        }
        DownloadQueue q = XDMApp.getInstance().getQueueById(queueId);
        if (q != null) {
            q.start();
        }
    }

    private void loadQueueMenu(JMenu menu) {
        if (menu.getName().equals("MENU_START_Q")) {
            loadStartQueueMenu(menu);
        } else if (menu.getName().equals("MENU_STOP_Q")) {
            loadStopQueueMenu(menu);
        }
    }

    private void loadStopQueueMenu(JMenu menu) {
        menu.removeAll();
        ArrayList<DownloadQueue> queues = XDMApp.getInstance().getQueueList();
        for (DownloadQueue q : queues) {
            if (q.isRunning()) {
                JMenuItem mitem = new JMenuItem(q.getName());
                mitem.setForeground(ColorResource.getLightFontColor());
                mitem.setName("STOP:" + q.getQueueId());
                mitem.addActionListener(this);
                menu.add(mitem);
            }
        }
    }

    private void loadStartQueueMenu(JMenu menu) {
        menu.removeAll();
        ArrayList<DownloadQueue> queues = XDMApp.getInstance().getQueueList();
        for (DownloadQueue q : queues) {
            if (!q.isRunning()) {
                JMenuItem mitem = new JMenuItem(q.getName());
                mitem.setForeground(ColorResource.getLightFontColor());
                mitem.setName("START:" + q.getQueueId());
                mitem.addActionListener(this);
                menu.add(mitem);
            }
        }
    }

    private void createPopupMenu() {
        popupCtx = new JPopupMenu();
        addMenuItem("MENU_PAUSE", popupCtx); // 暂停
        addMenuItem("MENU_RESUME", popupCtx); // 恢复
        addMenuItem("LBL_SHOW_PROGRESS", popupCtx); // 显示进度
        addMenuItem("CTX_OPEN_FILE", popupCtx); // 打开
        addMenuItem("CTX_OPEN_FOLDER", popupCtx); // 打开目录
        addMenuItem("CTX_SAVE_AS", popupCtx); // 保存为
        addMenuItem("MENU_DELETE_DWN", popupCtx); // 删除下载
        addMenuItem("MENU_REFRESH_LINK", popupCtx); // 刷新链接
        addMenuItem("DWN_PREVIEW", popupCtx); // 预览
        addMenuItem("CTX_COPY_URL", popupCtx); // 复制链接
        addMenuItem("CTX_COPY_FILE", popupCtx); // 复制文件
        addMenuItem("OPT_CONVERT", popupCtx); // 转换
        // convertMenu = createMenu(StringResource.get("OPT_CONVERT"));
        // convertMenu.setBorder(new EmptyBorder(5, 10, 5, 5));
        // convertMenu.setFont(FontResource.getNormalFont());
        //
        // MediaFormat[] fmts = MediaFormats.getSupportedFormats();
        // for (int i = 1; i < fmts.length; i++) {
        // MediaFormat fmt = fmts[i];
        // JMenuItem mitem = new JMenuItem(fmt.toString());
        // mitem.setName("FORMAT=" + i);
        // mitem.addActionListener(this);
        // convertMenu.add(mitem);
        // }
        //
        // popupCtx.add(convertMenu);

        addMenuItem("MENU_PROPERTIES", popupCtx);
        popupCtx.setInvoker(lv.getTable());
        lv.getTable().addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if (e.getClickCount() == 2) {
                    System.out.println("Opening file");
                    openFile();
                }
            }

            @Override
            public void mouseReleased(MouseEvent me) {
                // JOptionPane.showMessageDialog(null,"Mouse clicked:
                // "+me.getButton()+" "+MouseEvent.BUTTON3);
                if (me.getButton() == MouseEvent.BUTTON3 || SwingUtilities.isRightMouseButton(me) || me.isPopupTrigger()
                        || XDMUtils.isMacPopupTrigger(me)) {
                    Point p = me.getPoint();
                    JTable tbl = lv.getTable();
                    if (tbl.getRowCount() < 1)
                        return;
                    if (tbl.getSelectedRow() < 0) {
                        int row = tbl.rowAtPoint(p);
                        if (row >= 0) {
                            tbl.setRowSelectionInterval(row, row);
                        }
                    }
                    if (tbl.getSelectedRows().length > 0) {
                        popupCtx.show(lv.getTable(), me.getX(), me.getY());
                    }
                    // int row = tbl.rowAtPoint(p);
                    // if (row < 0) {
                    // tbl.setRowSelectionInterval(row, row);
                    // }
                }
            }
        });
    }

    private void showProperties() {
        String[] ids = lv.getSelectedIds();
        if (ids.length > 0) {
            String id = ids[0];
            DownloadEntry ent = XDMApp.getInstance().getEntry(id);
            if (id != null) {
                PropertiesPage propPage = PropertiesPage.getPage(this);
                HttpMetadata md = HttpMetadata.load(id);
                HeaderCollection headers = md.getHeaders();
                String referer = "";
                StringBuilder cookies = new StringBuilder();
                Iterator<HttpHeader> cookieIt = headers.getAll();
                while (cookieIt.hasNext()) {
                    HttpHeader header = cookieIt.next();
                    if ("referer".equalsIgnoreCase(header.getName())) {
                        referer = header.getValue();
                    }
                    if ("cookie".equalsIgnoreCase(header.getName())) {
                        cookies.append(header.getValue()).append("\n");
                    }
                }
                String type = "HTTP";
                if (md instanceof DashMetadata) {
                    type = "DASH";
                } else if (md instanceof HlsMetadata) {
                    type = "HLS";
                } else if (md instanceof HdsMetadata) {
                    type = "HDS";
                }

                propPage.setDetails(ent.getFile(), XDMApp.getInstance().getFolder(ent), ent.getSize(), md.getUrl(),
                        referer, ent.getDateStr(), cookies.toString(), type);
                propPage.showPanel();
            }
        }
    }

    public void openRefreshPage() {
        String[] ids = lv.getSelectedIds();
        if (ids.length > 0) {
            String id = ids[0];
            DownloadEntry ent = XDMApp.getInstance().getEntry(id);
            if (ent == null) {
                return;
            }
            if (!(ent.getState() == XDMConstants.PAUSED || ent.getState() == XDMConstants.FAILED)) {
                return;
            }
            try {
                HttpMetadata md = HttpMetadata.load(id);
                RefreshUrlPage rp = RefreshUrlPage.getPage(this);
                rp.setDetails(md);
                rp.showPanel();
            } catch (Exception e2) {
                Logger.log(e2);
            }
        }
    }

    public void openFile(String id) {
        DownloadEntry ent = XDMApp.getInstance().getEntry(id);
        if (ent != null) {
            if (ent.getState() == XDMConstants.FINISHED) {
                try {
                    XDMUtils.openFile(ent.getFile(), XDMApp.getInstance().getFolder(ent));
                } catch (FileNotFoundException e) {
                    Logger.log(e);
                    MessageBox.show(this, StringResource.get("ERR_MSG_FILE_NOT_FOUND"),
                            StringResource.get("ERR_MSG_FILE_NOT_FOUND_MSG"), MessageBox.OK, MessageBox.OK);
                } catch (Exception e) {
                    Logger.log(e);
                }
            }
        }
    }

    public void openFolder(String id) {
        DownloadEntry ent = XDMApp.getInstance().getEntry(id);
        if (ent != null) {
            if (ent.getState() == XDMConstants.FINISHED) {
                try {
                    XDMUtils.openFolder(ent.getFile(), XDMApp.getInstance().getFolder(ent));
                } catch (FileNotFoundException e) {
                    Logger.log(e);
                    MessageBox.show(this, StringResource.get("ERR_MSG_FILE_NOT_FOUND"),
                            StringResource.get("ERR_MSG_FILE_NOT_FOUND_MSG"), MessageBox.OK, MessageBox.OK);
                } catch (Exception e) {
                    Logger.log(e);
                }
            }
        }
    }

    private void showConversionWindow(String[] ids) {
        ArrayList<String> list = new ArrayList<>();

        for (String id : ids) {
            DownloadEntry ent = XDMApp.getInstance().getEntry(id);
            if (ent != null) {
                if (ent.getState() == XDMConstants.FINISHED) {
                    File f = new File(XDMApp.getInstance().getFolder(ent), ent.getFile());
                    if (f.exists()) {
                        list.add(f.getAbsolutePath());
                    }
                }
            }
        }
        if (list.size() > 0) {
            VideoConversionWnd cw = new VideoConversionWnd(list);
            cw.setVisible(true);
            cw.load();
        }
    }

    private void convert() {
        try {
            String[] ids = lv.getSelectedIds();
            if (ids.length > 0) {
                showConversionWindow(ids);
            }
        } catch (Exception e) {
            Logger.log(e);
        }
    }

    private void updateFFmpeg() {
        FFmpegDownloader fd = new FFmpegDownloader();
        fd.start();
    }

    private void changeFile(String id) {
        DownloadEntry ent = XDMApp.getInstance().getEntry(id);
        if (ent == null)
            return;
        if (ent.getState() == XDMConstants.FINISHED) {
            return;
        }
        JFileChooser jfc = new JFileChooser();
        jfc.setSelectedFile(
                new File(XDMApp.getInstance().getOutputFolder(id), XDMApp.getInstance().getOutputFile(id, false)));
        if (jfc.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) {
            File f = jfc.getSelectedFile();
            ent.setFolder(f.getParent());
            ent.setFile(f.getName());
            XDMApp.getInstance().fileNameChanged(id);
        }
    }

    private void showVideoDwnDlg() {
        MediaDownloaderWnd wnd = new MediaDownloaderWnd();
        wnd.setVisible(true);
    }

    private void showLanguageDlg() {
        Properties langMap = new Properties();
        InputStream in = null;
        try {
            in = StringResource.class.getResourceAsStream("/lang/map");
            if (in == null) {
                in = new FileInputStream("lang/map");
            }
            langMap.load(new InputStreamReader(in, StandardCharsets.UTF_8));
        } catch (Exception e) {
            Logger.log(e);
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (Exception ignored) {
                }
            }
        }

        int index = 0;

        ArrayList<String> keyList = new ArrayList<>(langMap.stringPropertyNames());
        Vector<String> valList = new Vector<>();

        for (int i = 0; i < keyList.size(); i++) {
            String name = keyList.get(i);
            String val = langMap.getProperty(name);
            valList.add(val);
            if (name.equals(Config.getInstance().getLanguage())) {
                index = i;
            }
        }

        JComboBox<String> cmbLang = new JComboBox<>(valList);
        cmbLang.setSelectedIndex(index);

        String prompt = StringResource.get("MSG_LANG1");

        Object[] obj = new Object[3];
        obj[0] = prompt;
        obj[1] = cmbLang;
        obj[2] = StringResource.get("MSG_LANG2");

        if (JOptionPane.showOptionDialog(null, obj, StringResource.get("MSG_LANG1"), JOptionPane.OK_CANCEL_OPTION,
                JOptionPane.PLAIN_MESSAGE, null, null, null) == JOptionPane.OK_OPTION) {
            index = cmbLang.getSelectedIndex();
            if (index != -1) {
                Config.getInstance().setLanguage(keyList.get(index));
            }
            String lang = langMap.getProperty(cmbLang.getSelectedItem() + "");
            if (lang != null)
                Config.getInstance().setLanguage(lang);
        }
    }

    public void showNotification() {
        int mode = XDMApp.getInstance().getNotification();
        if (mode == -1) {
            clearNotification();
            return;
        }
        if (updateNotifyPanel == null) {
            updateNotifyPanel = new UpdateNotifyPanel();
            toolbar.add(updateNotifyPanel, BorderLayout.SOUTH);
        }
        updateNotifyPanel.setDetails(mode);
        revalidate();
        repaint();
    }

    private void clearNotification() {
        if (updateNotifyPanel == null)
            return;
        updateNotifyPanel.setVisible(false);
        toolbar.remove(updateNotifyPanel);
        updateNotifyPanel = null;
        invalidate();
        repaint();
    }

    private void pauseDownloads() {
        String[] ids = lv.getSelectedIds();
        Set<String> queues = new HashSet<String>();
        for (int i = 0; i < ids.length; i++) {
            DownloadEntry ent = XDMApp.getInstance().getEntry(ids[i]);
            String qid = ent.getQueueId();
            queues.add(qid);
        }

        Iterator<String> qit = queues.iterator();
        boolean qRunning = false;
        while (qit.hasNext()) {
            String qid = qit.next();
            if (qid != null) {
                DownloadQueue q = XDMApp.getInstance().getQueueById(qid);
                if (q != null) {
                    if (q.isRunning()) {
                        qRunning = true;
                        break;
                    }
                }
            }
        }

        if (qRunning && (MessageBox.show(this, StringResource.get("MSG_REF_LINK_CONFIRM"),
                StringResource.get("LBL_STOP_Q"), MessageBox.YES_NO_OPTION, MessageBox.YES) == MessageBox.YES)) {
            qit = queues.iterator();
            while (qit.hasNext()) {
                String qid = qit.next();
                if (qid != null) {
                    DownloadQueue q = XDMApp.getInstance().getQueueById(qid);
                    if (q != null) {
                        if (q.isRunning()) {
                            q.stop();
                        }
                    }
                }
            }
        } else {
            for (String id : ids) {
                XDMApp.getInstance().pauseDownload(id);
            }
        }
    }

    private void openFile() {
        String[] ids = lv.getSelectedIds();
        if (ids.length > 0) {
            String id = ids[0];
            openFile(id);
        }
    }

    private void showBatchDialog() {
        List<String> urlList = BatchDownloadWnd.getUrls();
        if (urlList.size() > 0) {
            new BatchDownloadWnd(XDMUtils.toMetadata(urlList)).setVisible(true);
        } else {
            MessageBox.show(this, StringResource.get("MENU_BATCH_DOWNLOAD"),
                    StringResource.get("LBL_BATCH_EMPTY_CLIPBOARD"), MessageBox.OK_OPTION, MessageBox.OK);
        }
    }

    private void optimizeRWin() {
        JComboBox<String> cmbLang = new JComboBox<>(
                new String[]{StringResource.get("LBL_NET_OPT_DEF"), StringResource.get("LBL_NET_OPT_64"),
                        StringResource.get("LBL_NET_OPT_128"), StringResource.get("LBL_NET_OPT_256")});
        cmbLang.setSelectedIndex(0);

        String prompt = StringResource.get("LBL_NET_OPT_MSG");

        Object[] obj = new Object[2];
        obj[0] = prompt;
        obj[1] = cmbLang;

        switch (Config.getInstance().getTcpWindowSize()) {
            case 64 -> cmbLang.setSelectedIndex(1);
            case 128 -> cmbLang.setSelectedIndex(2);
            case 256 -> cmbLang.setSelectedIndex(3);
            default -> cmbLang.setSelectedIndex(0);
        }

        if (JOptionPane.showOptionDialog(null, obj, StringResource.get("LBL_OPTIMIZE_NETWORK"),
                JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE, null, null, null) == JOptionPane.OK_OPTION) {
            int index = cmbLang.getSelectedIndex();
            if (index != -1) {
                switch (index) {
                    case 1 -> Config.getInstance().setTcpWindowSize(64);
                    case 2 -> Config.getInstance().setTcpWindowSize(128);
                    case 3 -> Config.getInstance().setTcpWindowSize(256);
                    default -> Config.getInstance().setTcpWindowSize(0);
                }
            }
        }

    }

    private void openTranslationPage() {
        XDMUtils.browseURL("https://github.com/subhra74/xdm/wiki/Submitting-translations-for-XDM");
    }

    private void openSupportPage() {
        XDMUtils.browseURL("https://github.com/subhra74/xdm/wiki");
    }

    private void openBugReportPage() {
        XDMUtils.browseURL("https://github.com/subhra74/xdm/issues");
    }

    private int scale(int i) {
        return XDMUtils.getScaledInt(i);
    }

    private void showBatchPatternDialog() {
        new BatchPatternDialog().setVisible(true);
    }

    // void test() {
    // HttpMetadata m = new HttpMetadata();
    // m.setUrl("http://localhost:8080/x.zip");
    // HttpDownloader hd = new HttpDownloader(UUID.randomUUID().toString(),
    // "c:\\users\\subhro\\desktop\\temp", m,
    // new TestProxyResolver());
    // hd.registerListener(XDMApp.getInstance());
    // hd.start();
    // }

}
